<?php

/***

LZRoster: A roster for World of Warcraft.
Copyright (C) 2007  Emmanuel Cron

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

***/

require_once dirname(__FILE__)."/Sql.class.php";
require_once dirname(__FILE__)."/SessionRoster.class.php";
require_once dirname(__FILE__)."/Subscription.class.php";
require_once dirname(__FILE__)."/CharacterManager.class.php";

define ("SUBSCRIPTION_MANAGER_DOES_NOT_EXIST", 1);
define ("SUBSCRIPTION_MANAGER_NICKNAME_EXISTS", 2);
define ("SUBSCRIPTION_MANAGER_LOGIN_EXISTS", 3);

class SubscriptionManager
{
	static private $instance;
	
	private $cache = array();
	private $password_minimum_size = 5;
	private $max_best_uploaders = 5;
	
	private $sql;
	private $session_roster;

	private function __construct()
	{
		$this->sql = Sql::GetInstance();
		$this->session_roster = SessionRoster::GetInstance();
	}
	
	static function GetInstance()
	{
		if ( empty(self::$instance) )
		{
			self::$instance = new SubscriptionManager();
		}
		
		return self::$instance;
	}
	
	function HasName($name)
	{
		return $this->HasNicknameOrName(null, $name);
	}
	
	function HasNickname($nickname)
	{
		return $this->HasNicknameOrName($nickname, null);
	}
	
	function HasNicknameOrName($nickname, $name)
	{
		$name = strtolower($name);
		$nickname = mb_convert_case($nickname, MB_CASE_TITLE);
		
		foreach( $this->cache as $subscription )
		{
			if ( $subscription->GetNickname() == $nickname )
			{
				return SUBSCRIPTION_MANAGER_NICKNAME_EXISTS;
			}
			
			if ( $subscription->GetName() == $name)
			{
				return SUBSCRIPTION_MANAGER_LOGIN_EXISTS;
			}
		}
		
		$t_sql = "
			SELECT
				*
			FROM
				`cp_accounts`
			WHERE
		";
		
		if ( $name != null )
		{
			$t_sql .= "
				`account_name`='".$name."'
			";
		}
		
		if ( $name != null and $nickname != null )
		{
			$t_sql .= "
				OR
			";
		}
		
		if ( $nickname != null )
		{
			$t_sql .= "
				`account_nickname`='".$nickname."'
			";
		}
		
		$this->sql->Query($t_sql);
		
		if ( $this->sql->GetResultsNumber() > 0 )
		{
			$subscription = new Subscription( $this->sql->IterateResults() );
			
			$this->cache[$subscription->GetId()] = $subscription;
			
			if ( $subscription->GetNickname() == $nickname )
			{
				return SUBSCRIPTION_MANAGER_NICKNAME_EXISTS;
			}
			
			if ( $subscription->GetName() == $name)
			{
				return SUBSCRIPTION_MANAGER_LOGIN_EXISTS;
			}
		}
		else
		{
			return SUBSCRIPTION_MANAGER_DOES_NOT_EXIST;
		}
	}
	
	function IsAccountValid($name, $password)
	{
		$name = strtolower($name);
		$password = md5($password);
		
		foreach( $this->cache as $subscription )
		{
			if ( $subscription->GetName() == $name )
			{
				if ( $subscription->GetPassword() == $password )
				{
					return true;
				}
				else
				{
					return false;
				}
			}
		}
		
		$this->sql->Query("
			SELECT
				*
			FROM
				`cp_accounts`
			WHERE
				`account_name`='".$name."'
			AND
				`account_password`='".$password."'
		");
		
		if ( $this->sql->GetResultsNumber() > 0 )
		{
			$subscription = new Subscription( $this->sql->IterateResults() );
			$this->cache[$subscription->GetId()] = $subscription;
			
			return true;
		}
		else
		{
			return false;
		}
	}
	
	function IsSidValid($sid)
	{
		foreach( $this->cache as $subscription )
		{
			if ( $subscription->GetSid() == $sid )
			{
				return true;
			}
		}
		
		$this->sql->Query("
			SELECT
				*
			FROM
				`cp_accounts`
			WHERE
				`account_sid`='".$sid."'
		");
		
		if ( $this->sql->GetResultsNumber() > 0 )
		{
			$subscription = new Subscription( $this->sql->IterateResults() );
			
			$this->cache[$subscription->GetId()] = $subscription;
			
			return true;
		}
		else
		{
			return false;
		}
	}
	
	function GetBestUploaders()
	{
		$this->sql->Query("
			SELECT
				*
			FROM
				`cp_accounts`
			WHERE
				(`account_nb_items_updated`+`account_nb_spells_updated`+`account_nb_reagents_updated`) > 0
			ORDER BY
				(`account_nb_items_updated`+`account_nb_spells_updated`+`account_nb_reagents_updated`) DESC
			LIMIT
				".$this->max_best_uploaders."
		");
		
		while ( $data = $this->sql->IterateResults() )
		{
			$this->cache[$data['account_id']] = new Subscription($data);
		}
		
		return $this->cache;
	}
	
	function GetNbBestUploaders()
	{
		return $this->max_best_uploaders;
	}
	
	function GetAccountIdByName($name)
	{
		$name = strtolower($name);
		
		foreach( $this->cache as $subscription )
		{
			if ( $subscription->GetName() == $name )
			{
				return $subscription->GetId();
			}
		}
		
		return 0;
	}
	
	function GetAccountLocaleByName($name)
	{
		$name = strtolower($name);
		
		foreach( $this->cache as $subscription )
		{
			if ( $subscription->GetName() == $name )
			{
				return $subscription->GetLocale();
			}
		}
		
		return null;
	}
	
	function GetAccountIdBySid($sid)
	{
		foreach( $this->cache as $subscription )
		{
			if ( $subscription->GetSid() == $sid )
			{
				return $subscription->GetId();
			}
		}
		
		return 0;
	}
	
	function GetAccountLocaleBySid($sid)
	{
		foreach( $this->cache as $subscription )
		{
			if ( $subscription->GetSid() == $sid )
			{
				return $subscription->GetLocale();
			}
		}
		
		return null;
	}
	
	function Register($nickname, $name, $password, $locale)
	{
		if ($this->sql->Query("
			INSERT INTO
				`cp_accounts`
			SET
				`account_nickname`='".mb_convert_case($nickname, MB_CASE_TITLE)."',
				`account_name`='".strtolower($name)."',
				`account_password`='".md5($password)."',
				`account_creation`=NOW(),
				`account_locale`='".$locale."'
		") != true)
		{
			return false;
		}
		else
		{
			return true;
		}
	}
	
	function SetLocale($id, $locale)
	{
		if ($this->sql->Query("
			UPDATE
				`cp_accounts`
			SET
				`account_locale`='".$locale."'
			WHERE
				`account_id`='".$id."'
		") != true)
		{
			return false;
		}
		else
		{
			if ( array_key_exists($id, $this->cache) )
			{
				$this->cache[$id]->SetLocale($locale);
			}
			
			return true;
		}
	}
	
	function SetPassword($id, $password)
	{
		if ($this->sql->Query("
			UPDATE
				`cp_accounts`
			SET
				`account_password`='".md5($password)."'
			WHERE
				`account_id`='".$id."'
		") != true)
		{
			return false;
		}
		else
		{
			if ( array_key_exists($id, $this->cache) )
			{
				$this->cache[$id]->SetPassword($password);
			}
			
			return true;
		}
	}
	
	function SetSid($id, $sid)
	{
		if ($this->sql->Query("
			UPDATE
				`cp_accounts`
			SET
				`account_sid`='".$sid."'
			WHERE
				`account_id`='".$id."'
		") != true)
		{
			return false;
		}
		else
		{
			if ( array_key_exists($id, $this->cache) )
			{
				$this->cache[$id]->SetSid($sid);
			}
			
			return true;
		}
	}
	
	function UpdatePassword($id, $new_pass)
	{
		if ($this->sql->Query("
			UPDATE
				`cp_accounts`
			SET
				`account_password`='".md5($new_pass)."'
			WHERE
				`account_id`='".$id."'
		") != true)
		{
			return false;
		}
		else
		{
			if ( array_key_exists($id, $this->cache) )
			{
				$this->cache[$id]->SetPassword($new_pass);
			}
			
			return true;
		}
	}
	
	function UpdateNickname($id, $new_nickname)
	{
		if ($this->sql->Query("
			UPDATE
				`cp_accounts`
			SET
				`account_nickname`='".mb_convert_case($new_nickname, MB_CASE_TITLE)."'
			WHERE
				`account_id`='".$id."'
		") != true)
		{
			return false;
		}
		else
		{
			if ( array_key_exists($id, $this->cache) )
			{
				$this->cache[$id]->SetNickName($new_nickname);
			}
			
			return true;
		}
	}
	
	function GetSubscription($id)
	{
		if ( array_key_exists($id, $this->cache) )
		{
			return $this->cache[$id];
		}
		
		$this->sql->Query("
			SELECT
				*
			FROM
				`cp_accounts`
			WHERE
				`account_id` = '".$id."'
		");
		
		if ( $this->sql->GetResultsNumber() > 0)
		{
			$subscription = new Subscription( $this->sql->IterateResults() );
			
			$this->cache[$subscription->GetId()] = $subscription;
			
			return $subscription;
		}
		else
		{
			if ( $this->session_roster->IsConnected() and $id == $this->session_roster->GetAccountId() )
			{
				$this->session_roster->Redirect("disconnection.php");
			}
			
			return null;
		}
	}
	
	function CheckNameAndNickname($name, $nickname)
	{
		if ( strtolower($name) == strtolower($nickname) )
		{
			return false;
		}
		
		return true;
	}
	
	function CheckPassword($pass)
	{
		if ( strlen($pass) < $this->password_minimum_size )
		{
			return false;
		}
		else
		{
			return true;
		}
	}
	
	function GetAllAccounts()
	{
		$this->sql->Query("
			SELECT
				*
			FROM
				`cp_accounts`
			ORDER BY
				`account_name`
		");
		
		while ( $v = $this->sql->IterateResults() )
		{
			$subscription = new Subscription($v);
			
			$this->cache[$subscription->GetId()] = $subscription;
		}
		
		return $this->cache;
	}
	
	function GetPasswordMinimumSize()
	{
		return $this->password_minimum_size;
	}
	
	function Delete($id)
	{
		$character_manager = CharacterManager::GetInstance();
		
		if ($this->sql->Query("
			SELECT
				`cp_characters`.*
			FROM
				`cp_accounts`
			LEFT JOIN
				`cp_characters`
			ON
				`cp_accounts`.`account_id`=`cp_characters`.`character_account_id`
			WHERE
				`cp_accounts`.`account_id`='".$id."'
		") != true)
		{
			return false;
		}
		
		while ( $v = $this->sql->IterateResults() )
		{
			if ( $character_manager->DeleteCharacter($v['Name']) == false)
			{
				return false;
			}
		}
		
		if ( $this->sql->Query("
			DELETE FROM
				`cp_accounts`
			WHERE
				`account_id`='".$id."'
		") != true)
		{
			return false;
		}
		
		return true;
	}
}

?>